package cc.comac.saic.hkhy.jsrj.gj.inttools.async;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import cc.comac.saic.hkhy.jsrj.gj.common.core.utils.StringUtils;
import cc.comac.saic.hkhy.jsrj.gj.common.json.utils.JsonUtils;
import cc.comac.saic.hkhy.jsrj.gj.inttools.pojo.entity.SysAsyncTask;
import cc.comac.saic.hkhy.jsrj.gj.inttools.service.SysAsyncTaskService;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class AsyncTaskExecutor {

    // 存储任务取消状态
    private final Map<Long, Boolean> taskCancelMap = new ConcurrentHashMap<>();
    @Autowired
    private SysAsyncTaskService asyncTaskService;

    /**
     * 创建并执行异步任务（推荐使用）
     */
    @Async
    @Transactional
    public void executeTask(String taskName,
                            String taskType,
                            Map<String, Object> taskParams,
                            Long operator,
                            Consumer<AsyncTaskContext> taskFunction) {
        // 创建任务记录
        Long taskId = createTaskRecord(taskName, taskType, taskParams, operator);

        // 执行任务
        executeExistingTask(taskId, taskFunction);
    }

    /**
     * 执行已存在的任务
     */
    @Async
    public void executeExistingTask(Long taskId, Consumer<AsyncTaskContext> taskFunction) {
        AsyncTaskContext context = new AsyncTaskContext(taskId, this::updateProgress, this::isCancelled);

        try {
            // 更新任务状态为执行中
            asyncTaskService.updateTaskStatus(taskId, AsyncTaskStatus.RUNNING.getCode(), null);

            // 执行任务
            taskFunction.accept(context);

            // 任务执行成功
            if (!context.isCancelled()) {
                String result = JsonUtils.toJsonString(context.getResult());
                asyncTaskService.updateTaskResult(taskId, result, AsyncTaskStatus.SUCCESS.getCode());
                log.info("异步任务执行成功，任务ID：{}", taskId);
            }

        } catch (Exception e) {
            log.error("异步任务执行失败，任务ID：" + taskId, e);
            asyncTaskService.updateTaskStatus(taskId, AsyncTaskStatus.FAILED.getCode(),
                // 限制错误信息长度
                StringUtils.substring(e.getMessage(), 0, 1000));
        } finally {
            taskCancelMap.remove(taskId);
        }
    }

    /**
     * 创建任务记录
     */
    @Transactional
    public Long createTaskRecord(String taskName, String taskType, Map<String, Object> taskParams, Long operator) {
        SysAsyncTask task = new SysAsyncTask();
        task.setName(taskName);
        task.setType(taskType);
        if (taskParams != null && !taskParams.isEmpty()) {
            task.setParams(JsonUtils.toJsonString(taskParams));
        }
        task.setStatus(AsyncTaskStatus.PENDING.getCode());
        task.setProgress(0);
        task.setCreateBy(operator);
        task.setStartTime(new Date());

        asyncTaskService.createTask(task);
        log.info("创建异步任务记录，任务ID：{}，任务名称：{}", task.getId(), taskName);
        return task.getId();
    }

    /**
     * 创建任务记录（重载方法，支持自定义实体）
     */
    @Transactional
    public Long createTaskRecord(SysAsyncTask task) {
        if (StringUtils.isEmpty(task.getStatus())) {
            task.setStatus(AsyncTaskStatus.PENDING.getCode());
        }
        if (task.getProgress() == null) {
            task.setProgress(0);
        }

        asyncTaskService.createTask(task);
        return task.getId();
    }

    private void updateProgress(Long taskId, Integer progress) {
        asyncTaskService.updateTaskProgress(taskId, progress);
    }

    private boolean isCancelled(Long taskId) {
        return taskCancelMap.getOrDefault(taskId, false);
    }

    public void cancelTask(Long taskId) {
        taskCancelMap.put(taskId, true);
        asyncTaskService.updateTaskStatus(taskId, AsyncTaskStatus.CANCELLED.getCode(), "任务已被取消");
    }

    // 获取任务状态
    public SysAsyncTask getTaskStatus(Long taskId) {
        return asyncTaskService.getTaskById(taskId);
    }

    @FunctionalInterface
    public interface ProgressUpdater {
        void update(Long taskId, Integer progress);
    }

    @FunctionalInterface
    public interface CancellationChecker {
        boolean isCancelled(Long taskId);
    }

    // 内部类保持不变
    public static class AsyncTaskContext {
        @Getter
        private final Long taskId;
        private final ProgressUpdater progressUpdater;
        private final CancellationChecker cancellationChecker;
        @Getter
        private final Map<String, Object> result = new ConcurrentHashMap<>();

        public AsyncTaskContext(Long taskId, ProgressUpdater progressUpdater, CancellationChecker cancellationChecker) {
            this.taskId = taskId;
            this.progressUpdater = progressUpdater;
            this.cancellationChecker = cancellationChecker;
        }

        public void updateProgress(int progress) {
            if (progressUpdater != null) {
                progressUpdater.update(taskId, Math.min(100, Math.max(0, progress)));
            }
        }

        public boolean isCancelled() {
            return cancellationChecker != null && cancellationChecker.isCancelled(taskId);
        }

        public void addResult(String key, Object value) {
            result.put(key, value);
        }

    }
}
